package com.gqr.threadobjectclasscommonmethods;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * Copyright (C), 2020-2024,gqr
 * FileName:ProducerConsumerModel
 * author:guqingrong
 * Date:2024-04-22 21:50
 * Description:用wait/notify来实现生产者和消费者   这里要配合前面的 synchronized 找到锁是谁
 * History:
 * <author>    <time>    <version>    <desc>
 * 作者姓名     修改时间     版本号        描述
 */
public class ProducerConsumerModel {

    public static void main(String[] args) {
        EventStorage eventStorage = new EventStorage();
        Producer producer = new Producer(eventStorage);
        Consumer consumer = new Consumer(eventStorage);
        Thread threadProducer = new Thread(producer);
        Thread threadConsumer = new Thread(consumer);
        threadProducer.start();
        threadConsumer.start();

    }
}
class Producer implements Runnable{
    private EventStorage storage;

    public Producer(EventStorage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            storage.put();
        }
    }
}

class Consumer implements Runnable{
    private EventStorage storage;

    public Consumer(EventStorage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            storage.take();
        }
    }
}


class EventStorage{
    private int maxSize;
    private LinkedList<Date> storage;

    public EventStorage(){
        maxSize = 10;
        storage = new LinkedList<>();
    }

    public synchronized void put(){

        // 满了就等待 阻塞
        while (storage.size()==maxSize){
            try {
                System.out.println("put 进入阻塞状态, monitor锁释放出来");
                wait();
                System.out.println("put唤醒了");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        storage.add(new Date());
        System.out.println("仓库里有了"+storage.size()+"个产品");
        notify();
//        System.out.println("put中的notify");

    }

    public synchronized void take(){
//        System.out.println("进入take");
        while (storage.size()==0){
            try {
                System.out.println("take 进入阻塞状态, monitor锁释放出来");
                wait();
                System.out.println("take 唤醒了");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("拿到了"+storage.poll()+",现在仓库还剩下"+storage.size());
        notify();
//        System.out.println("take中的notify");
    }
}
